<template>
    <div :id="graphId" style="flex:1;"></div>
</template>
<script>
import { Graph } from '@antv/x6'
import {
    createDefaultSetting
} from '../config/graph.js'
import { inject } from '@vue/runtime-core'
export default {
    props: {
        graphId: {
            default: 'main',
            type: [String, Number]
        }
    },
    setup (props) {
        const editor = inject('editor')
        // 接受外部函数
        const cellClickCallback = inject('cellClickCallback')
        // 创建 画布 对象
        const init = () => {
            // #region 初始化画布
            editor.graph = new Graph({
                ...createDefaultSetting(props.graphId, `${props.graphId}map`)
            })
            bindKey()
            bindPortsSetting()
        }

        // 绑定画布的键盘事件
        const bindKey = () => {
            bindKeyCopy()
            bindKeyPaste()
            bindKeyShear()
            bindKeyUndo()
            bindKeyRedo()
            bindKeySelectAll()
            bindKeyDel()
        }
        // 绑定键盘事件 复制
        const bindKeyCopy = () => {
            editor.graph.bindKey(['meta+c', 'ctrl+c'], () => {
                // getSelectedCells 获取节点
                const cells = editor.graph.getSelectedCells()
                if (cells.length) {
                    editor.graph.copy(cells)
                }
                return false
            })
        }
        // 绑定键盘事件 粘贴
        const bindKeyPaste = () => {
            editor.graph.bindKey(['meta+v', 'ctrl+v'], () => {
                // cleanSelection 清空选区
                if (!editor.graph.isClipboardEmpty()) {
                    const cells = editor.graph.paste({ offset: 32 })
                    editor.graph.cleanSelection()
                    editor.graph.select(cells)
                }
                return false
            })
        }
        // 绑定键盘事件 剪切
        const bindKeyShear = () => {
            editor.graph.bindKey(['meta+x', 'ctrl+x'], () => {
                const cells = editor.graph.getSelectedCells()
                if (cells.length) {
                    editor.graph.cut(cells)
                }
                return false
            })
        }
        // 绑定键盘事件 撤销
        const bindKeyUndo = () => {
            editor.graph.bindKey(['meta+z', 'ctrl+z'], () => {
                if (editor.graph.history.canUndo()) {
                    editor.graph.history.undo()
                }
                return false
            })
        }
        // 绑定键盘事件 重做
        const bindKeyRedo = () => {
            editor.graph.bindKey(['meta+shift+z', 'ctrl+shift+z'], () => {
                if (editor.graph.history.canRedo()) {
                    editor.graph.history.redo()
                }
                return false
            })
        }
        // 绑定键盘事件 全选
        const bindKeySelectAll = () => {
            editor.graph.bindKey(['meta+a', 'ctrl+a'], () => {
                const nodes = editor.graph.getNodes()
                if (nodes) {
                    editor.graph.select(nodes)
                }
            })
        }
        // 绑定键盘事件 删除
        const bindKeyDel = () => {
            editor.graph.bindKey('backspace', () => {
                const cells = editor.graph.getSelectedCells()
                if (cells.length) {
                    editor.graph.removeCells(cells)
                }
            })
        }

        // 绑定节点设置
        const bindPortsSetting = () => {
            // 控制连接桩显示/隐藏 鼠标经过元素时候的展示节点
            const showPorts = (ports, show) => {
                for (let i = 0, len = ports.length; i < len; i = i + 1) {
                    ports[i].style.visibility = show ? 'visible' : 'hidden'
                }
            }
            nodeMouseenter(showPorts)
            nodeMouseleave(showPorts)
            nodeClick()
        }
        // 鼠标移入
        const nodeMouseenter = (showPorts) => {
            editor.graph.on('node:mouseenter', () => {
                const container = document.getElementById(props.graphId)
                const ports = container.querySelectorAll('.x6-port-body')
                showPorts(ports, true)
            })
        }
        // 鼠标移出
        const nodeMouseleave = (showPorts) => {
            editor.graph.on('node:mouseleave', () => {
                const container = document.getElementById(props.graphId)
                const ports = container.querySelectorAll('.x6-port-body')
                showPorts(ports, false)
            })
        }
        // 鼠标点击
        const nodeClick = () => {
            editor.graph.on('cell:click', ({ e, x, y, cell, view }) => {
                cellClickCallback(cell)
            })
        }

        return {
            init
        }
    }
}
</script>
